package main

import (
	"log"
	"net"
	"sync"
	"time"

	"gitee.com/gricks/utils"

	"github.com/golang/protobuf/proto"
)

var (
	forwarder *Forwarder
)

var (
	waiter sync.WaitGroup
)

func main() {
	l, err := net.Listen("tcp", GC_Host)
	if err != nil {
		panic(err)
	}

	forwarder = NewForwarder(15, GC_UserCount) // 15 frame per sec
	go forwarder.Start()

	for i := 0; i < GC_UserCount; i++ {
		waiter.Add(1)
		go Dial(uint32(i))
	}

	go func() {
		for {
			conn, err := l.Accept()
			if err != nil {
				panic(err)
			}

			// go Auth
			// find the right forwarder
			// close when auth failure
			// close when idle long time without auth
			// if Success
			go Auth(conn)
		}
	}()

	waiter.Wait()
}

func Auth(c net.Conn) {
	ses := NewSession(c, GC_ReadBuffer, GC_WriteBuffer)
	f, err := ses.Codec.Read()
	if err != nil {
		panic(err)
	}
	if f.Proto != CC_Auth {
		log.Println("Auth must be first proto")
		return
	}
	r := &AuthRequest{}
	err = proto.Unmarshal(f.Content, r)
	if err != nil {
		panic(err)
	}

	// TODO: verify expire
	signa, err := Decryp(utils.Hex2Byte(r.Sign))
	if err != nil {
		panic(err)
	}
	ses.Gid, ses.Uid = signa.Gid, signa.Uid

	log.Println("Start Auth:", ses.Gid, ses.Uid)

	// TODO: find forwarder by number
	forwarder.AddSession(ses)
}

func Dial(Uid uint32) {
	defer waiter.Done()

	time.Sleep(100 * time.Millisecond)

	signature := &Signature{
		Gid: 1,
		Uid: Uid,
	}

	b, _ := Encryp(signature)
	sign := utils.Byte2Hex(b)
	u := NewUser(1, Uid, GC_MessageCount, sign, "127.0.0.1"+GC_Host)
	if err := u.Auth(); err != nil {
		log.Println("Auth Err:", err)
		return
	}
	if err := u.Forward(); err != nil {
		log.Println("Forward Err:", err)
		return
	}

	log.Println("Send Complete")
}
